/*
 * 版权所有 (C) 2021 中国南方航空股份有限公司。
 * 本文件可能包含有南方航空公司的机密或专有信息。
 * 未经许可不得擅自公开、复制这些机密资料及其中任何部分，
 * 只可按照其使用许可协议，在南方航空公司内部使用。
 *
 * File Name: $(#)ForkJoinTaskDemo.java
 * Creation Date: 2021年11月30日 下午2:13:03
 * $Id$
 */
package com.andy.note.main.concurrent.forkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 统计 1-10000000 结果，长度能整除则计算，不能整除则拆分
 * 
 * @author zhouguoan 908119428@qq.com
 * @version $Revision: 1.1 $ $Date: 2021年11月30日 下午2:13:03 $
 */
public class ForkJoinTaskDemo extends RecursiveTask<Long> {
    
    private static final long serialVersionUID = 1376168713220811020L;
    
    private List<Long> list;
    public ForkJoinTaskDemo(List<Long> list) {
        this.list = list;
    }

    @Override
    protected Long compute() {
        // 长度不能整除的则进行计算
        if(list.size() % 2 != 0) {
            long result = 0;
            for(Long l : list) {
                result += l;
            }
            return result;
        } else {
            // 切分成2个任务进行计算
            int middle = list.size() / 2;
            List<Long> subList1 = list.subList(0, middle);
            List<Long> subList2 = list.subList(middle , list.size());

            ForkJoinTaskDemo leftForkJoin = new ForkJoinTaskDemo(subList1);
            ForkJoinTaskDemo rightForkJoin = new ForkJoinTaskDemo(subList2);
            
              // 方法一： 各自处理再合并
            leftForkJoin.fork();
            rightForkJoin.fork();
            // 将结果合并
            return leftForkJoin.join() + rightForkJoin.join();
            
            // 方法二： 合并成一个list统一处理
//            List<ForkJoinTaskDemo> forkList = new ArrayList<>();
//            forkList.add(leftForkJoin);
//            forkList.add(rightForkJoin);
//            Collection<ForkJoinTaskDemo> invokeAll = invokeAll(forkList);
//            long result = 0;
//            for (ForkJoinTaskDemo demo : invokeAll) {
//                try {
//                    result += demo.get();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                } 
//            }
//            return result;
            
        }
    }

    public static void main(String[] args) {
        List<Long> list = new ArrayList<>();
        Long total = 0L;
        for(long i = 1; i <= 10000000; i++) {
            list.add(i);
            total += i;
        }
        System.err.println(total);
        ForkJoinTaskDemo forkJoinTaskDemo = new ForkJoinTaskDemo(list);
        ForkJoinPool pool = new ForkJoinPool();
        Long result = pool.invoke(forkJoinTaskDemo);
        pool.shutdown();
        System.out.println(result);
    }
}
